import { player_position, render_all } from './render_box.js'
import { map, correct, WALL, BOX, SPACE, PLAYER } from './map.js'

const CURRENT_LEVEL = 'current_level'

class Game {
    constructor() {
        this.level = Number(localStorage.getItem(CURRENT_LEVEL)) || 0  // 当前关卡
        this.total_level = map.length   // 总关卡数
        this.render()
    }

    get_map() {
        return map[this.level]
    }

    get_correct() {
        return correct[this.level]
    }

    render() {
        render_all(this.level)
        // 渲染之后才可以得到玩家位置
        this.player_row = player_position.row
        this.player_col = player_position.col
    }

    start() {
        document.onkeydown = this.move.bind(this)
    }

    move(e) {
        const { next_row, next_col } = this.get_next(e.key)
        const map = this.get_map()
        const next_value = map[next_row][next_col]

        if (next_value === SPACE) {
            // 下一块是空白，直接移动
            map[this.player_row][this.player_col] = SPACE
            map[next_row][next_col] = PLAYER
        } else if (next_value === WALL) {
            // 下一块是墙，什么都不做
            return;
        } else if (next_value === BOX) {
            // 下一块是箱子
            const next_two = this.get_next(e.key, 2)
            if (map[next_two.next_row][next_two.next_col] !== SPACE) {
                return;
            }
            // 下下一块是空白，推箱子
            map[this.player_row][this.player_col] = SPACE
            map[next_row][next_col] = PLAYER
            map[next_two.next_row][next_two.next_col] = BOX
        }
        this.render()
        this.is_victory()
    }

    // 获取下一个方块的值、行、列
    get_next(key, n = 1) {
        let row = this.player_row,
            col = this.player_col;
        if (key === 'ArrowUp') {
            row -= n
        } else if (key === 'ArrowDown') {
            row += n
        } else if (key === 'ArrowLeft') {
            col -= n
        } else if (key === 'ArrowRight') {
            col += n
        }
        return { next_row: row, next_col: col }
    }

    is_victory() {
        const map = this.get_map()
        const correct = this.get_correct()

        const victory = correct.every(item => map[item.row][item.col] === BOX)
        if (victory) {
            this.level++
            setTimeout(() => {
                if (this.level < this.total_level) {
                    localStorage.setItem(CURRENT_LEVEL, this.level)
                    window.alert('恭喜过关！')
                    this.render()
                } else {
                    window.alert('恭喜你，通关了！！！')
                    this.over()
                }
            }, 50)
        }
    }

    over() {
        document.onkeydown = null
    }
}

export default Game;